Для начала вы можете начать с этого простого цикла bash for:
for i in {001..250} ; do touch ./file$i ; done
Это создаст 250 пустых файлов в текущем каталоге с именами от file001 до file250.
Тач (в данном случае) просто создает файл, если он не существует. Пустой файл.
Если вы хотите создать файлы с чем-то внутри, вы можете изменить часть do
цикла for
. Например, do cp ./master.file ./newfile.$i
— файл с именем master.file будет скопирован в 250 новых файлов, которые будут называться newfile.001 до newfile.250.
Это слишком запутанно? Мне потребовалось некоторое время, чтобы понять, как все это работает в bash, но как только мне это удалось, я использую его почти каждый день. Так что не стесняйтесь спрашивать, я постараюсь объяснить это подробнее и/или лучше.
Если у вас есть только одна запись для каждого файла, это простой цикл чтения.
#!/bin/bash
read_data()
{
local first last addr city state zip
file=$1
while read -r header data
do
case $header in
FirstName:) first=$data ;;
LastName:) last=$data ;;
Address:) addr=$data ;;
City:) city=$data ;;
State:) state=$data ;;
Zip:) zip=$data ;;
*) echo Ignoring bad line $header $data >&2
esac
done < $file
echo "$file,$first,$last,$addr,$city,$state,$zip"
}
for file in *srcfiles*
do
read_data $file
done
Функция read_data
считывает каждую строку и разбивает строку на «заголовок» и «данные». Дойдя до конца файла, мы просто распечатываем результаты.
Мы вызываем эту функцию один раз для каждого исходного файла с помощью цикла for
.
Обратите внимание на некоторые возможные подводные камни: если в данных есть запятые, это сломает ситуацию, поэтому вы можете сделать
echo "\"$file\",\"$first\",\"$last\",\"$addr\",\"$city\",\"$state\",\"$zip\""
в качестве вывода, чтобы заключить все внутри "..."
макета. Если в данных есть "
, это может привести к неправильному формату CSV.
Отрегулируйте строку echo
, чтобы она соответствовала желаемому формату.
Если есть одна запись на файл и у вас есть GNU awk, вы можете сделать
gawk -F': +' -vOFS=, '
BEGINFILE{delete rec}
{rec[$1] = $2}
ENDFILE{print FILENAME, rec["FirstName"], rec["City"], rec["Zip"]}
' file1.txt file2.txt ...
Быстрый и грязный подход, может удовлетворить ваши требования.
grep . *|perl -ne 'if(/FirstName: (.*)/){$f=$1}if(/City: (.*)/){$c=$1}if(/^(.*):Zip: (.*)/){print "$1,$f,$c,$2\n"}'
Пример:
grep . *
f1.txt:FirstName: Mary
f1.txt:LastName: Smith
f1.txt:Address: 123 Anywhere St
f1.txt:City: Nowhere
f1.txt:State: TX
f1.txt:Zip: 77777
f2.txt:FirstName: Joe
f2.txt:LastName: Bloggs
f2.txt:Address: 444 Anywhere St
f2.txt:City: Nowhere2
f2.txt:State: TXA
f2.txt:Zip: 77737
grep . *|perl -ne 'if(/FirstName: (.*)/){$f=$1}if(/City: (.*)/){$c=$1}if(/^(.*):Zip: (.*)/){print "$1,$f,$c,$2\n"}'
f1.txt,Mary,Nowhere,77777
f2.txt,Joe,Nowhere2,77737