使用 sed 或 awk,当下一行以相同内容开头并后跟斜杠时,如何删除一行?
有一个 Zsh 变量,其内容如下:
$if(description-meta)$
<meta name="description" content="$description-meta$" />
$endif$
<title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
<style>
$styles.html()$
</style>
$for(css)$
<link rel="stylesheet" href="$css$" />
$endfor$
我需要删除 <title>
这一行,即:
<title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
并覆盖该变量或创建一个新变量,使其变为:
$if(description-meta)$
<meta name="description" content="$description-meta$" />
$endif$
<style>
$styles.html()$
</style>
$for(css)$
<link rel="stylesheet" href="$css$" />
$endfor$
如何使用 awk
或 sed
来实现?
我正在尝试将以下内容添加到我的 .bashrc 中:
cpu_info() {
top -b -n1 | grep Cpu(s) | awk '{print $2 + $4}'
}
但 bash 告诉我:
bash: .bashrc: line 131: syntax error near unexpected token `('
bash: .bashrc: line 131: ` top -b -n1 | grep Cpu(s) | awk '{print $2 + $4}''
该命令在终端中运行良好,不知道为什么它会破坏我的 bash 脚本
有任何想法吗?
我使用此语法删除2.txt
to中的行1.txt
:
awk 'NR==FNR{a[$0]=1;next}!a[$0]' 2.txt 1.txt > lines.txt
我的行采用以下格式:
[email protected]:something
如果这行在两个文件中是相同的,我就lines.txt
没有这个,所以很好,但是如果[email protected]
相同的话我想删除行并忽略后面的单词:
。
我想自动注释掉PHP文件中的代码块,如下所示:
原始块:
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
带注释的新块:
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
所以我打算将这些行放在两个文件中,并使用 sed 自动执行替换。然而,在网上搜索后,我只找到Replace string with content of a file using sed和sed - Replace string with file content,这意味着要么只有源模式或目标模式在一个文件中,其余的在网上。但文件中没有两者的样本。
那么,如何进行更换呢?我应该使用 sed 还是 awk?
有一个包含内容的文件
{
"first_name": "John",
"last_name": "Smith",
"is_alive": true,
"age": 27,
"address": {
"street_address": "21 2nd Street",
"city": "New York",
"state": "NY",
"postal_code": "10021-3100"
},
"phone_numbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [
"Catherine",
"Thomas",
"Trevor"
],
"spouse": null
}
如何使用 Busybox 实用程序将内容添加到文件最后一个 } 字符之前,以使文件内容如下所示?
{
"first_name": "John",
"last_name": "Smith",
"is_alive": true,
"age": 27,
"address": {
"street_address": "21 2nd Street",
"city": "New York",
"state": "NY",
"postal_code": "10021-3100"
},
"phone_numbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [
"Catherine",
"Thomas",
"Trevor"
],
"spouse": null,
"field1": "value1",
"field2": "value2",
"field3": "value3",
"field4": "value4"
}
但是,} 字符不一定是文件中的最后一个字符,也不一定位于最后一行。
到目前为止我只找到了这个解决方案
tac file2 | sed '0,/}/s/}/}\n"field4": "value4"\n"field3": "value3",\n"field2": "value2",\n"field1": "value1",\n,/' | tac>tmp_file && mv tmp_file file2
测试用例:(使用非 root 用户,因为 root 会忽略 000 权限...)
#in a clean directory:
[ -f file_1 ] && chmod 600 file_? # for repeat tests...
for i in file_1 file_2 file_3; do
printf 'A\nB\n' > "$i"
# we need at least 1 char : awk/gawk silently skips empty files...
done
chmod 000 file_2
awk '(FNR==1) { print FILENAME }' file_?
# tried with : regular (old unixes) awk on AIX. and gawk on Linux.
# the fatal "permission denied" on file_2 stops [g]awk.
有没有办法捕获该致命错误并继续处理下一个文件?
(否则我觉得这很令人担忧:对一堆文件使用 awk 并不能保证处理所有文件,因为如果其中任何一个文件不可读,它将致命地退出)
如果可以的话请:回答
- 对于常规 awk,
- 和傻瓜
- 还有其他相关的 awk 版本吗?(诺克?等)
简单而快速的问题。
我有这个
awk -f file # awk use file as input
awk '/word/' file # awk show me word
awk '/32$/' text # all words with 32..
我要这个
# awk use file as input
awk -f file
# awk show me word
awk '/word/' file
# all words with 32..
awk '/32$/' text
可以使用 awk 来做到这一点吗?也欢迎使用其他命令(perl、sed、python ..)
我有一个文件,报告某件事的每个事件及其大小。我试图通过合并连续的事件来总结该信息,这些事件可以通过上面一行的第 3 列与下面一行的第 2 列相同来识别(只要第 1 列相同),输出应该是相同的格式,而不是任何连续字符串的多行,我会将其替换为单行,其中第 2 列将是该列中分组中的最低数字,第 3 列将是该列中分组中的最高数字,第 4 列将是该分组第 4 列中所有数字的平均值(四舍五入到最接近的整数)。
需要明确的是,第一列是特定组,第二列是开始位置,第三列是结束位置,第四列是出现次数。
每行的列组合都是唯一的,列按第 1 列、第 2 列、第 3 列进行预排序。第 2 列中的数字不应该/不会相同,第 3 列中的数字不应该/不会相同是相同的。第一列可以而且通常会是相同的。
如果可能的话,我试图在 awk 中实现这一点,我已经尝试过但失败了。这是我尝试过的:
awk 'BEGIN {OFS=","} NR==1 {print} NR>1 {if ($1==prev && $2==end+1) {sum+=$4; count++; end=$3} else {if (NR>2) {print prev, start, end, int(sum/count+0.5);}; prev=$1; start=$2; end=$3; sum=$4; count=1}} END {print prev, start, end, int(sum/count+0.5)}'
###### reformatted via "awk -o- '...script_body...'"
awk '
BEGIN {
OFS = ","
}
NR == 1 {
print
}
NR > 1 {
if ($1 == prev && $2 == end + 1) {
sum += $4
count++
end = $3
} else {
if (NR > 2) {
print prev, start, end, int(sum / count + 0.5)
}
prev = $1
start = $2
end = $3
sum = $4
count = 1
}
}
END {
print prev, start, end, int(sum / count + 0.5)
}'
输入示例:
fgh1,45513382,45513383,43
fgh1,45513383,45513384,44
fgh1,45513384,45513385,44
fgh1,45513385,45513386,43
fgh1,45513386,45513387,43
fgh1,45513387,45513388,44
fgh2,63543512,63543513,44
fgh2,63543513,63543514,41
fgh2,63543514,63543515,44
fgh2,63543515,63543516,44
输出示例:
fgh1,45513382,45513388,44
fgh2,63543512,63543516,43
要对同一个输入文件进行多次传递,这个简单的情况可以正常工作:
$ awk 'p==1{print $1}; p==2{print $2}; p==3{print $3}' p=1 infile p=2 infile p=3 infile
但这个改变失败了吗?
$ awk 'p==1{/Jan/ {print $1}}; p==2{print $2}; p==3{print $3}' p=1 infile p=2 infile p=3 infile
我不想使用这样的术语:
p==1 && /Jan/ {print $1}
因为我想保持(原始)代码的可读结构。
如何在每个括号内使用条件术语?
例子:
$ cat infile
James Exeter 48
Alex Leeds 22
Jan London 35
期望的结果:
Jan
Exeter
Leeds
London
48
22
35