Reputation: 21
I found this command to work great:
awk -v "/mallory:/,/end-config/ {next} 1" /filename.txt
It takes everything in a file like this:
alice:
config option 1
config option 2
end-config
mallory: <--- Line gets deleted
config option 1 <--- Line gets deleted
config option 2 <--- Line gets deleted
end-config <--- Line gets deleted
bob:
config option 1
config option 2
end-config
and only deletes the config block for mallory.
So now I wanted to define this in a bash script, so username could be a bash variable. I did this:
#!/bin/bash
username="mallory"
awk -v username="$username" "/username:/,/end-config/ {next} 1" /file.txt
Guess what. It doesn't remove anything. The output matches the file I started with. What gives? I imported my variable correctly, right?
Upvotes: 0
Views: 1323
Reputation: 7610
/username:/
matches exactly the string You have written and nothing to do with the environment variable, but awk can read the environment variables. I would suggest:
username=mallory
awk '$0 == ENVIRON["username] ":",/end-config/ {next} 1' /file.txt
Actually this is not the nicest solution, as in the result there is double empty lines. So if username=mallory
is set, then the result is:
alice:
config option 1
config option 2
end-config
bob:
config option 1
config option 2
end-config
But maybe it is ok for You.
Upvotes: 0
Reputation: 61467
"/username:/,/end-config/ {next}"
username
will be literal there. To match against a variable, you have to use an explicit pattern match:
awk -v username="mallory" '
$0 ~ (username ":"),/end-config/ {next}
1'
Upvotes: 0
Reputation: 107090
The /foo/,/bar/
is the range of addresses where your {next}
statement will work. And, addresses must be literals. Geekosaur's answer does work with a bit of tweaking:
awk -v username="mallory" '
$0 ~ (username ":"),/end-config/ {next}
1' filename.txt
The 1
is needed for awk
to do anything. A better way may be:
awk -v username="mallory" '
$0 ~ (username ":"),/end-config/ {next}
{print $0}' filename.txt
Which states that your printing the line {print $0}
if you don't skip it via the {next}
statement. Awk prints the line if given no other commands and it returns a true (non-zero) value.
Upvotes: 1
Reputation: 63974
bit shorter with sed - save the following into file e.g. confdel.sh
sed "/^$1:/,/end-config/d"
and use it like:
bash confdel.sh mallory < config_file.txt
Upvotes: 0
Reputation: 112424
Alternatively, you could use
#!/bin/bash
username="mallory"
awk -v "/${username}:/,/end-config/ {next} 1" /file.txt
Remember that the shell will do shell interpolation before the program gets to AWK, so ${username}
will be replaced by mallory
. To be more safe, you might want to use
#!/bin/bash
username="mallory"
awk -v '/'"${username}"':/,/end-config/ {next} 1' /file.txt
which will ensure that the awk program is protected from any other shell interpretation.
Upvotes: 1