#bash #awk #cut
#bash #awk #вырезать
Вопрос:
У меня есть один файл, представляющий собой список чисел, и другой файл (с тем же количеством строк), в котором мне нужна длина каждой строки, чтобы соответствовать номеру строки в другом файле. Например:
файл 1:
5
8
7
11
15
файл 2:
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
вывод:
abcde
abcdefgh
abcdefg
abcdefghijk
abcdefghijklmno
Я пытался использовать awk и вырезать вместе, но я продолжаю получать ошибку «фатальная: попытка использовать массив `line’ в скалярном контексте». Я не уверен, как еще это сделать. Мы высоко ценим любые рекомендации!
Комментарии:
1. Покажите свой код, чтобы мы могли помочь вам найти эту ошибку.
Ответ №1:
awk
вероятно, более уместно, но вы также можете сделать:
while read line <amp;3; do
read len <amp;4; echo "${line:0:$len}";
done 3< file2 4< file1
Комментарии:
1.
while IFS= read -u3 -r line amp;amp; IFS= read -u4 -r len
— необходимо очистить IFS и использовать -r, чтобы получить строки дословно из файла.
Ответ №2:
awk — ваш инструмент для этого: один из
# read all the lengths, then process file2
awk 'NR == FNR {len[NR] = $1; next} {print substr($0, 1, len[FNR])}' file1 file2
# fetch a line from file1 whilst processing file2
awk '{getline len < lenfile; print substr($0, 1, len)}' lenfile=file1 file2
Комментарии:
1. Кажется, оба они отлично работают! Большое спасибо за вашу помощь!
Ответ №3:
другой awk
$ paste file1 file2 | awk '{print substr($2,1,$1)}'
abcde
abcdefgh
abcdefg
abcdefghijk
abcdefghijklmno
Комментарии:
1. Это потрясающе, но у вас возникнут проблемы, если «$ 2» содержит пробелы.
2. Да, в этом случае вы можете установить разделитель полей на tab.
3. Проблема в том, что нет способа узнать, какая FS безопасна, поскольку мы не знаем содержимого file2. awk использует
34
в качестве значения SUBSEP, которое может быть безопасным.
Ответ №4:
Использование Perl
perl -lne ' BEGIN { open($f,"file1.txt");@x=<$f>;close($f) }
print substr($_,0,$x[$.-1]) ' file2.txt
с заданными входными данными
$ cat cmswen1.txt
5
8
7
11
15
$ cat cmswen2.txt
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
$ perl -lne ' BEGIN { open($f,"cmswen1.txt");@x=<$f>;close($f) } print substr($_,0,$x[$.-1]) ' cmswen2.txt
abcde
abcdefgh
abcdefg
abcdefghijk
abcdefghijklmno
$
Комментарии:
1. кажется неправильным вызывать cat из perl:
open $f, "<", "cmswen1.txt"; @x = <$f>; close $f
2. спасибо @glennjackman, да, я тоже чувствовал то же самое.. просто привычка писать короткие ответы одолевает меня 🙂 .. в любом случае обновлено…