Можно ли перечислить файлы между двумя именами в алфавитно-цифровом порядке?

Как сказал steeldriver, разумный способ сделать это - paste:

$ paste -d';' file*
1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004

Но если вы должны использовать awk:

$ awk '{a[FNR]=a[FNR](FNR==NR?"":";")$0} END{for (i=1;i<=FNR;i++) print a[i]}' file*
1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004

Сценарий awk хранит все данные в памяти. Если файлы большие, это может стать проблемой. Но, для этой задачи, paste в любом случае лучше и проще.

Как это работает

В этом скрипте a - массив, а a[i] - вывод для строки i. По мере чтения каждого из последующих файлов мы добавляем новую информацию для строки i в конец a[i]. После завершения чтения файлов мы выводим значения в a. Более подробно:

  • a[FNR]=a[FNR](FNR==NR?"":";"")$0

    FNR - это номер строки текущего файла, который мы читаем, а $0 - содержимое этой строки. Этот код добавляет $0 в конец a[FNR]. Если мы все еще читаем первый файл, то перед $0 ставится точка с запятой. Это делается с помощью сложного троичного оператора: (FNR==NR?"":";"). На самом деле это просто команда if-then-else. Если мы читаем первый файл, то есть если FNR==NR, то она возвращает пустую строку """. Если нет, то возвращается точка с запятой, ;.

  • END{for (i=1;i<=FNR;i++) print a[i]}

    После завершения чтения всех файлов выводит данные, которые мы накопили в массиве a.

3
26.09.2016, 02:09
2 ответа

Этого, безусловно, можно добиться, направив вывод в awk

ls | awk '/^20160909_154038\.jpg$/,/^20160908_121201\.jpg$/'
3
27.01.2020, 21:15

sed версия:

ls 2016090*.jpg | sed -n '/9_154038/,/8_121201/p'
2
27.01.2020, 21:15

Теги

Похожие вопросы