set '%s_q1.out %s_q2.out %s_q3.out\n'
:|for d in several directories
do cd -P -- "$d" || ! break
set "$1" "../${PWD##*/}"
{ sed -ne'\|\( \.\./a_a_q[123]\.out\)\{3\}|q;s/.//p'
printf "$@" "$2" "$2"; cut -c2-
} <<-IN >./infile
$(paste -d\ - ./infile)
IN
done
Isso deve funcionar com um POSIX sed e um bash , zsh , ksh , mksh shell e muitos outros. Com um dash ou yash shell, o documento here provavelmente não terá um arquivo regular e, portanto, não é possível confiar na função lseek() necessária para suportar o compartilhamento. Nesses casos, você deve mudar para uma das shells acima mencionadas.
Se você usar um GNU sed , você vai querer usar sed -une em vez de apenas sed -ne .
Aqui está um resumo:
-
Primeiro, nós usaremos set um argumento como a string de formato printf repetidamente e definiremos ambos $PWD e $OLDPWD para .
-
Em seguida, iniciamos a iteração de itens em several directories . Sejam eles diretórios ou links simbólicos reais, obtemos o nome de caminho canônico e -P em $PWD e set do último componente de caminho para $2 .
-
A próxima coisa que acontece ocorre na parte inferior do redirecionamento heredoc. paste lê todo o ./infile para algum arquivo temporário seguro que o shell assegurou para nós enquanto prefixava um único espaço em cada linha. O shell então define esse arquivo temporário para stdin e ./infile é novamente designado - mas desta vez como stdout.
-
sed faz muito pouca edição. Até encontrar sua linha de correspondência, ele remove o primeiro caractere de cada linha e p solicita os resultados. Uma vez que ele encontra sua linha, a entrada q uits é totalmente - nada é impresso.
-
Mas printf imprime ../${PWD##*/}_q[123].out seguido por uma nova linha para stdout e depois cut escolhe stdin em que sed deixou (logo após a sua linha de correspondência) e lê o resto enquanto tira o primeiro byte de cada linha de entrada.
E assim todo o ./infile editado acaba de volta de onde veio.
Oh, eu testei isso.
Substitui o bit several directories pelo nome de caminho /tmp e fiz ...
{ seq 7
echo '../a_a_q1.out ../a_a_q2.out ../a_a_q3.out'
seq 9 14
printf %s\n '' '' ''
} >/tmp/infile
... que escreveu um /tmp/infile que parecia:
1
2
3
4
5
6
7
../a_a_q1.out ../a_a_q2.out ../a_a_q3.out
9
10
11
12
13
14
Depois de executar o snippet de código acima em /tmp , embora ...
cat /tmp/infile
1
2
3
4
5
6
7
../tmp_q1.out ../tmp_q2.out ../tmp_q3.out
9
10
11
12
13
14