Обработка текста перед печатью в awk

# save valid extension from listB
vexts=($(sed "s/^.*\.//g" listB))
# loop over listA and filter desired output
while read line; do 
    if [[ " ${vexts[@]} " == *" ${line##*.} "* ]] ; then
        echo "${line}";
    fi
done < listA
3
02.10.2021, 11:32
5 ответов

Вам никогда не понадобится sed, если вы используете awk. Если каталог, который вы хотите, всегда 3-й -последний в пути, как в ваших примерах, тогда все, что вам нужно, это использовать любой awk:

$ awk '{print $3, $6, $7, $8, p[split($8,p,"/")-2]}' file
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

В противном случае используйте GNU awk для соответствия 3-го аргумента():

$ awk '{match($8,"([^/]+)/main/",a); print $3, $6, $7, $8, a[1]}' file
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

или используя любой awk:

$ awk '{match($8,"[^/]+/main/"); print $3, $6, $7, $8, substr($8,RSTART,RLENGTH-6)}' file
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4
7
02.10.2021, 12:41

Я действительно не понимаю, зачем вам sedтам, вы можете сделать это с помощью всего одного awk. Конечно, это предполагает, что у вас никогда не будет пробелов или новых строк в именах папок, и мы можем безопасно использовать пробелы в качестве разделителя полей. Пожалуйста, отредактируйте свой вопрос и добавьте более полный пример, если это не так.

$ awk '{ 
            split($8,dirs,"/");
            dir="" 
            for(i in dirs){ 
                if(dirs[i+1]=="main"){
                    dir=dirs[i]
                } 
            } 
            print $3,$6,$7,$8,dir}' fileY
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

Хитрость здесь заключается в использовании split()для разделения 8-го поля на массив dirs, используя /в качестве разделителя. Затем мы перебираем dirsи сохраняем последний найденный элемент массива, чей следующий элемент массива — main. Обратите внимание, что это означает, что если у вас есть более одного вхождения main, вы будете соответствовать только последнему.

4
02.10.2021, 12:37

Другой подход, использующий rev, с использованием того факта, что требуемая папка является третьим элементом в обратном порядке, используя /в качестве разделителя, предполагая, что структура имени папки соответствует приведенному образцу(<wanted folder>/main/summary.txt):

$ rev file | awk -F'/' '{ print $3,$0 }' | rev | awk '{ print $3,$6,$7,$8,$9 }'
user1 2021-09-07 2000 /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08 1400 /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09 1800 /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4

3
02.10.2021, 12:52

Вы можете сделать это так же легко с помощью sed, для этого я определяю некоторые вспомогательные переменные оболочки, чтобы помочь в написании кода sed. Использование GNU sed в режиме расширенного регулярного выражения.

на основе наблюдений @Ed Morton разделители теперь представляют собой двоеточие, чтобы избежать путаницы с регулярным выражением ERE char |

_s='[:space:]'
s="[${_s}]" S="[^${_s}]" F="$S+$s+"
sed -Ee "
  s:^($F){2}($F)($F){2}:\2:
  s:/([^/]+)/main/$S+\$:& \1:
" file
0
02.10.2021, 20:24

Использование GNU sedвложенная группировка

$ sed -E 's|.*\s[0-9]\s\s(.[^ ]*).*([0-9]{4}-.*/(.[^/]*).*/.*/.*)|\1 \2 \3|' input_file
user1 2021-09-07  2000  /folder/subfolder1/subfolder2/subfolder3/main/summary.txt subfolder3
user1 2021-09-08  1400  /folder/subfolder1/subfolder2/main/summary.txt subfolder2
user1 2021-09-09  1800  /folder/subfolder1/subfolder2/subfolder3/subfolder4/main/summary.txt subfolder4
0
03.10.2021, 21:30

Теги

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