Ich habe diese Datei
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
und ich möchte awk verwenden, um eine Zeile nach/vor dem Muster einzufügen 127.0.0.1
. Muster und Zeile sind Bash-Variablen.
#!/bin/bash
file="test.txt"
pattern='127.0.0.1'
line='127.0.1.1 cent.centurian.com centurian'
awk -vpattern="$pattern" -vline="$line" '/pattern/{print;print line;next}1' "$file"
Funktioniert nicht...
Antwort1
sed
ist einfacher:
sed "/$pattern/a\
$line" "$file"
Ausgabe:
127.0.0.1 localhost
127.0.1.1 cent.centurian.com centurian
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
GNU sed
ermöglicht eine einzeilige Version des obigen:
sed $file -e "/$pattern/a $line"
...und zur Ausgabe$line
Vor $pattern
, ändere dasa
(anhängen)zu einemi
(einfügen):
sed $file -e "/$pattern/i $line"
Antwort2
Schließen. Das sucht nach dem (wörtlichen) Muster pattern
.
Sie müssen es $0 ~ pattern
zum Abgleichen mit einer Variablen verwenden.
$ pattern='127.0.0.1'
$ line='127.0.1.1 cent.centurian.com centurian'
$ awk -vpattern="$pattern" -vline="$line" '$0 ~ pattern {print; print line; next} 1' $file | head -2
127.0.0.1 localhost
127.0.1.1 cent.centurian.com centurian
Antwort3
Habe gerade eine Funktion erstellt, die Folgendes macht:
################################################################################
## Adds a line in a file. ##
#------------------------------------------------------------------------------#
# Given the arguments: #
# 1st: file #
# 2nd: string to find #
# 3rd: line to add #
# 4th: 'b' for before, 'a' for after. #
# It adds a line before or after the line containing the search string. #
################################################################################
function addLineInFileOnString() {
local file pattern line where tmp
file="$1"
pattern="$2"
line="$3"
where="$4"
tmp="$( cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1 )"
tmp='tmp.'$tmp
if [[ $where == 'b' ]]; then
awk -v pattern="$pattern" -v line="$line" '$0 ~ pattern {print line; print; next} 1' "$file" | tee 1>/dev/null $tmp
elif [[ $where == 'a' ]]; then
awk -v pattern="$pattern" -v line="$line" '$0 ~ pattern {print; print line; next} 1' "$file" | tee 1>/dev/null $tmp
fi
[[ -e $tmp ]] && cp "$tmp" "$file" && rm "$tmp"
}
Antwort4
Vor der übereinstimmenden Zeile:
awk -v line='127.0.1.1 cent.centurian.com centurian' '/127\.0\.0\.1/ \
{ printf "%s\n%s\n", line, $0; next }; 1' file.txt
Nach der übereinstimmenden Zeile:
awk -v line='127.0.1.1 cent.centurian.com centurian' '/127\.0\.0\.1/ \
{ printf "%s\n%s\n", $0, line; next }; 1' file.txt
/127\.0\.0\.1/
entspricht dem MusterWenn das Muster übereinstimmt, wird die gewünschte formatierte Ausgabe gedruckt, je nachdem,
printf
ob die Variableline
vor oder nach der übereinstimmenden Zeile steht.
Beispiel:
$ cat file.txt
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
$ awk -v line='127.0.1.1 cent.centurian.com centurian' '/127\.0\.0\.1/ { printf "%s\n%s\n", $0, line; next }; 1' file.txt
127.0.0.1 localhost
127.0.1.1 cent.centurian.com centurian
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
$ awk -v line='127.0.1.1 cent.centurian.com centurian' '/127\.0\.0\.1/ { printf "%s\n%s\n", line, $0; next }; 1' file.txt
127.0.1.1 cent.centurian.com centurian
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters