Используйте bash для сокращения строк в одном файле до длины, явно указанной в другом

#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, да, я тоже чувствовал то же самое.. просто привычка писать короткие ответы одолевает меня 🙂 .. в любом случае обновлено…