все решения, использующие awk/sed/grep, кажутся слишком сложными и уродливыми для моей ситуации... поэтому я придумал это действительно простое решение, НО будьте осторожны, потому что оно делает некоторые предположения, а именно предположение, что ПОСЛЕДНИЙ интерфейс является единственным тебе это интересно. если вы согласны с этим, то это довольно чисто:
ifconfig | awk '/net / { x = $2 } END { print x }'
в противном случае вы могли бы сделать какой-нибудь глупый оператор if
для проверки определенного префикса или любого другого критерия, который у вас может быть.
Для этого можно использовать следующий скрипт. Из вашего вопроса непонятно, как именно вы определяете «основной» файл для каждого входного файла. В приведенном ниже сценарии предполагается, что это единственный другой файл в папке.
#!/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
Если я вас правильно понял (см. комментарий ), 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
)и удаляет новую строку,поэтому вы должны получить желаемый результат 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.
Вы можете использовать группы захвата в 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