Como criar arquivos com o nome de linhas em um arquivo de texto no Linux

6

Eu tenho um arquivo de texto que contém uma lista de itens (um para cada linha) e eu preciso criar, em um determinado diretório, um arquivo para cada entrada na lista; Cada um desses arquivos deve ser nomeado com uma string na lista. Além disso, se possível, após a string contida no arquivo de texto, um texto personalizado deve ser anexado aos nomes de arquivo.

Quais comandos devo usar para fazer isso a partir da linha de comando? Suponho que cat , grep e touch (e talvez xargs ?) Devam estar envolvidos no processo, mas depois de algumas tentativas ainda não consigo encontrar a sintaxe correta.

Alguém pode me esclarecer sobre isso?

    
por Sekhemty 01.05.2013 / 23:07

2 respostas

9

Digamos que você tenha list.txt assim:

file 1
file 2
file 3

Você pode conseguir o que quiser com:

while read FILE; do touch "${FILE} some string"; done < list.txt
    
por 01.05.2013 / 23:20
7

Então você tem um arquivo list que contém:

this
that
the-other

e você deseja criar, para cada linha desse arquivo, um arquivo com o nome dado nessa linha. Isso é muito fácil - se e somente se cada linha consistir apenas em uma única palavra:

cat list | xargs touch --

(O -- diz ao touch para não tentar analisar nada depois dele como argumento; sem ele, se você tiver nomes de arquivo como -this , o - inicial irá confundir o toque em pensamento 't' 'h', 'i' e 's' são significados como argumentos, em vez de partes do nome do arquivo literal a serem tocados.)

Esse é o caso simples resolvido, mas não é o que você pediu; se você quiser que o nome do arquivo contenha algum texto além do especificado nas linhas em list , as coisas ficam mais complicadas; xargs não podem fazer esse tipo de interpolação. Em vez disso, você precisaria de algo como o seguinte (que exige que seu shell seja bash , como é padrão na maioria dos sistemas):

for file in 'cat list'; do touch -- $file-customtext; done

Tenha em atenção que isto apenas funciona se cada linha consistir apenas numa única palavra. Nesse comando, $file é substituído pelo nome de arquivo especificado em uma determinada linha em list ; tudo ao redor é tomado literalmente, então este comando com o conteúdo list acima criaria os seguintes arquivos:

this-customtext
that-customtext
the-other-customtext

Você pode substituir '-customtext' com o que quiser, é claro, e também pode ter um prefixo e um sufixo; se você tivesse do touch -- some-$file-text , por exemplo, funcionaria bem e resultaria em arquivos com o nome some-this-text & c.

Agora, suponhamos que o conteúdo de list não seja tão simples - especificamente, que eles contenham espaços, caracteres não pertencentes à palavra ou outras coisas que o shell não interprete corretamente. Se você perguntar a três pessoas o que elas recomendariam nesse caso, você provavelmente obteria cinco respostas; Eu sou um hacker Perl, então minha resposta é Perl. Especificamente, vamos supor que list contenha:

This is the first line
of three (three?) lines
in the list file.

A maneira que eu faria isso seria:

cat list | perl -ne'chomp; system(qq|touch -- "custom $_ text"|)'

Que produz os arquivos resultantes:

custom This is the first line text
custom of three (three?) lines text
custom in the list file. text

O texto personalizado, neste caso, pode ser o que você quiser, espaços e todos, desde que não contenha " (que confundirá touch ) nem ' (que confundirá perl ); no comando Perl, $_ representa o conteúdo de uma determinada linha de list e o texto personalizado pertence antes ou depois, mas entre aspas duplas. (O texto personalizado fora das aspas duplas será considerado por touch como um nome de arquivo separado, que será literalmente criado, a menos que contenha algo que faça com que touch cometa erros.)

    
por 01.05.2013 / 23:22