Mam katalog pełen plików tekstowych. Moim celem jest dołączenie tekstu na początku i na końcu wszystkich. Tekst znajdujący się na początku i na końcu jest taki sam dla każdego pliku.
Na podstawie kodu, który otrzymałem z sieci, oto kod do dołączania na początku pliku:
echo -e "var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)" > $BASEDIR/Translations/Javascript/*.txt
To jest kod do dołączania na końcu pliku. Celem jest dodanie tekstu };
na końcu każdego pliku:
echo "};" >> $BASEDIR/Translations/Javascript/*.txt
Przykłady, z których czerpałem służyły do działania na poszczególnych aktach. Pomyślałem, że „spróbuję działać na wielu plikach, używając symbolu wieloznacznego, *.txt
.
Mogę też popełniać inne błędy. W każdym razie, jak mam dołączyć tekst na początku i na końcu wielu plików?
Odpowiedź
Aby wstawić tekst na początku do pliku, którego możesz użyć (z Implementacja GNU sed
):
sed -i "1i some string" file
Dołączanie tekstu jest tak proste, jak
echo "Some other string" >> file
Ostatnią rzeczą do zrobienia jest umieszczenie tego w pętli, która iteruje po wszystkich plikach, które zamierzasz edytować:
for file in *.txt; do sed -i "1i Some string" "$file" && echo "Some other string" >> "$file" done
Odpowiedź
Możesz użyć GNU sed
Jak już pokazano, możesz wstawić wiersze tekstu tuż przed i po dopasowaniu wiersze pliku z sed
, używając odpowiednio poleceń i
i a
. Co nie „Pokazano, że możesz to zrobić za pomocą jednej linijki i dla wiele plików naraz.
Poniższy tekst wstawi wiersz przed pierwszym 1i
a po ostatniej linii $a
. Wstawienia zostaną wykonane dla wszystkich plików pasujących do globu *.txt
.
sed -i -e "1ivar language = {" -e "$a};" -- *.txt
Oba i a
działają nie tylko z numerami wierszy, ale także z każdym wierszem, który pasuje do danego wzorca. Spowoduje to wstawienie komentarza za każdym razem, gdy wiersz zawiera var y = 2;
:
sed -i -- "/var y = 2;/i//initialize variable y" *.js
Odpowiedź
Polecenie w pełni zgodne z POSIX, używając ex
:
for f in *.txt; do printf "%s\n" 0a "var language = {" . "$a" "};" . x | ex "$f"; done
Jeśli uruchomisz samą printf
część polecenia, zobaczysz dokładne polecenia edycji, które przechodzi do ex
:
0a var language = { . $a }; . x
0a
oznacza „Dołącz tekst po linii 0 ”(innymi słowy, przed pierwszą linią). Następna linia to dosłowny tekst, który ma zostać „dołączony” po linii 0. Kropka (.
) w wierszu sama w sobie kończy dołączany tekst.
$a
oznacza dodanie tekstu po ostatniej linii pliku.
x
oznacza zapisanie zmian i wyjście .
Odpowiedź
Oto sposób na zrobienie tego w Perlu:
for f in ./*txt; do perl -lpe "BEGIN{print "First string"}END{print "Last string"}" "$f" > foo && mv foo "$f"; done
Komentarze
Odpowiedź
Ma również prawo być (z wynikami w .out
plikach):
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.out" \;
Kolejny, bardziej rozbudowany wariant – pliki źródłowe zastąpione wynikiem:
find . -name "*.txt" -exec sh -c "(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}" \; -print
Odpowiedz
Spróbuj użyć ex
:
ex -s +"bufdo!1s/^/HEAD/|$s/$/TAIL/" -cxa *.foo
gdzie polecenia to:
-
bufdo!
wykonuje poniższe polecenia dla każdego otwartego bufora / pliku (uwaga: to nie jest POSIX ) -
1s/^/HEAD/
– wstawia tekstHEAD
do pierwszego wiersza na początku wiersza -
$s/$/TAIL/
– dodajeTAIL
tekst w ostatnim wierszu na końcu wiersza
i argumentami są:
-
-s
– tryb cichy / szybki -
-cxa
– zapisz wszystkie otwarte bufory / pliki i zakończ -
*.foo
– wszystkie pliki w bieżącym katalogu (*
) zfoo
rozszerzenie, użyj**/*.foo
do rekurencji (po włączeniu globstar:shopt -s globstar
)
Komentarze
- uwaga bufdo nie jest w standardzie POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
- @StevenPenny ma rację. Osobiście używam tylko funkcji określonych w standardzie POSIX do edycji skryptów.
Odpowiedź
Z gnu awk
, używając inplace
rozszerzenie i BEGINFILE
/ ENDFILE
:
gawk -i inplace "BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1" ./*.txt
Odpowiedź
Jedna linijka Perla na ratunek:
perl -i -pe"$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof" *.txt
-i
zamiast tego podstawianie pliku nie działa nie , po prostu drukuje na standardowe wyjście.