grep имена файлов из текстового файла и вывести имя файла оболочки, вызывающего этот файл, в текст

все решения, использующие awk/sed/grep, кажутся слишком сложными и уродливыми для моей ситуации... поэтому я придумал это действительно простое решение, НО будьте осторожны, потому что оно делает некоторые предположения, а именно предположение, что ПОСЛЕДНИЙ интерфейс является единственным тебе это интересно. если вы согласны с этим, то это довольно чисто:

ifconfig | awk '/net / { x = $2 } END { print x }'

в противном случае вы могли бы сделать какой-нибудь глупый оператор ifдля проверки определенного префикса или любого другого критерия, который у вас может быть.

1
12.09.2019, 14:18
4 ответа

Для этого можно использовать следующий скрипт. Из вашего вопроса непонятно, как именно вы определяете «основной» файл для каждого входного файла. В приведенном ниже сценарии предполагается, что это единственный другой файл в папке.

#!/usr/bin/env bash

while IFS= read -r f  # every line is represented by $f
do
    d=$(dirname "$f") # $f's directory
    b=$(basename "$f") # $f's basename
    bwoe=${b%.*} # $f's basename without extension
    m=$(find "$d" -mindepth 1 -maxdepth 1 -not -name "$b" | head -n 1) # get first file in the folder that is not $f
    m=$(basename "$m") # basename of main file
    printf "%s\\t%s\\t%s\\n" "$f" "$bwoe" "$m"
done < input.txt # input.txt contains the input scripts

Пример:

$ ls a b c
a:
afoo.sh  a.sh

b:
bmain.sh  b.sh

c:
c.sh  cxx.sh
$ cat input.txt 
a/a.sh
b/b.sh
c/c.sh
$ bash script.sh 
a/a.sh  a       afoo.sh
b/b.sh  b       bmain.sh
c/c.sh  c       cxx.sh
0
28.01.2020, 00:00

Если я вас правильно понял (см. комментарий ), GNU sedфлаг eк команде sможет помочь вам сделать ее одной -строкой (непроверенной, извините):

sed -E 'h;s_(.*/)(.*)_grep -l \2 \1*.sh_e;x;G;s_([^/]*).sh\n_\1.sh \1 _' scriptfile
  • hсохраняет строку в резервной области, чтобы мы могли восстановить ее позже, если испортим ее
  • s_.*/_grep -l \2 \1*.sh_e— это настоящий трюк.:.*/соответствует всему до последней косой черты, поэтому \1будет путем, а \2— оставшейся частью строки (— именем скрипта ). Теперь grep -lвставляется перед именем скрипта и перед путем; таким образом /my/path/foo.shстановится grep -l foo.sh /my/path/*.sh. Флаг eвыполняет этот шаблон в оболочке, поэтому он заменяется списком файлов *.shв /my/path, которые содержат foo.sh(, надеюсь, только один, в противном случае скрипт необходимо адаптировать)
  • Остальное просто:xизмените оба буфера и добавьте буфер хранения (теперь с ответом оболочки )на шаблон
  • s_([^/]*).sh\n_\1.sh \1 _выполняет очистку, дублирует имя сценария (без.sh)и удаляет новую строку,поэтому вы должны получить желаемый результат
0
28.01.2020, 00:00

c-shellможет стать здесь настоящим спасителем:

% foreach line ( "`cat./input.txt`" )
   printf '%s\t%s\t' ${line:q} ${line:r:t:q}
   printf '%smain\n' ${line:r:t:q}
end

Другими методами являются:

$ perl -F/ -pale '
   my($t) = $F[-1] =~ /([^.]+)/;
   $_ = join "\t", $_, $t, "${t}main" if /\S/;
'./input.txt

$ sed -Ee '
   s|([^/.]+)\.[^/.]+$|&\t\1\t\1main|;t
   s|([^.]+)\.[^.]+$|&\t\1\t\1main|;t
   s|([^/]+)$|&\t\1\t\1main|
'./input.txt

Результаты:

/myhome/new1/myfiles/test2.sh   test2   test2main
/myhome/new3/myfiles/test1.sh   test1   test1main
/myhome/new2/myfiles/test4.sh   test4   test4main
/myhome/new/myfiles/test5.sh    test5   test5main

Примечания:

o We have to be verbose as we need to cover the various possible cases that may arise.
o GNU sed is needed.
0
28.01.2020, 00:00

Вы можете использовать группы захвата в sed с расширенным регулярным выражением (-параметром r ), чтобы получить имя файла и заменить исходную строку вместе с вашими скриптами в конечном выводе:

sed -r 's/(^.*\/)([^.]*)(.*$)/\1\2\3 \2 \2main/' test.txt 

(^.*\/) -- 1st Capture, the path 
([^.]*) -- 2nd Capture, the file up to the dot 
(.*$)   -- 3rd Capture, the file suffix 
0
28.01.2020, 00:00

Теги

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