以下是text.txt中的文字:
“ word1 Word2 word3 ”
现在,我希望得到这个输出:
“ nword1 Nword2 nword3 ”
到目前为止我做了什么:
sed -e s/word1/nword1/gI text.txt
sed -e s/word2/nword2/gI text.txt
sed -e s/word3/nword3/gI text.txt
事情是我不知道哪个字有大写字母。因此我必须以小写形式输入“sed -e s / word3 / nword3 / gI text.txt”。
所以基本上,我想替换原始文本大写的单词。我怎样才能在bash脚本中执行此操作?
答案 0 :(得分:1)
的Perl
perl -CSDA -plE 'BEGIN{$f=shift@ARGV;$t=lc(shift@ARGV)}s/(?i)\b($f)\b/$1=~m!^\p{Upper}!?ucfirst $t:$t/xge;' word nword
该解决方案不仅可以将N
添加到word
,还可以将任何给定的单词转换为另一个单词,保留原始单词大写。
更具可读性
perl -CSDA -plE '
BEGIN{ $f = shift @ARGV; $t = lc(shift @ARGV) }
s/ (?i) \b($f)\b/ $1 =~ m!^\p{Upper}! ? ucfirst $t : $t /xge;
' word nword
但建议你创建一个bash function
,然后称之为casesubs
casesubs() {
#usage: casesubs fromword toword
perl -CSDA -plE 'BEGIN{$f=shift@ARGV;$t=lc(shift@ARGV)}s/(?i)\b($f)\b/$1=~m!^\p{Upper}!?ucfirst $t:$t/xge;' "$1" "$2"
}
现在您可以轻松地将其用作以下示例:
(
text='abcword word Word word wordlen';
echo "$text"
casesubs word nword <<<"$text"
) | column -t #pretty printing
abcword word Word word wordlen #orig
abcword nword Nword nword wordlen #changed
该解决方案适用于任何utf8编码的Unicode,例如不仅[a-z]
。
(
text='überJägermeister ÜBERJÄGERMEISTER'
echo "$text"
casesubs überJägermeister unterPIÑACOLÁDA <<<"$text"
) | column -t
输出
überJägermeister ÜBERJÄGERMEISTER
unterpiñacoláda Unterpiñacoláda
和文件也是如此,例如拥有内容
的文件capfile.txt
Ut debitis eveniet molestiae iusto quis ut. Est nemo dolores
error ipsum aut überJägermeister ÜBERJÄGERMEISTER. Numquam
itaque molestias ut iusto. Quia ut nobis expedita.
可以使用
casesubs überJägermeister unterPIÑACOLÁDA < capfile.txt
并获取
Ut debitis eveniet molestiae iusto quis ut. Est nemo dolores
error ipsum aut unterpiñacoláda Unterpiñacoláda. Numquam
itaque molestias ut iusto. Quia ut nobis expedita.
答案 1 :(得分:1)
或者我们可以使用简单的bash:
foo(x,y)
答案 2 :(得分:0)
您可以使用awk
:
awk '{for(i=1; i<NR; i++) { if ($i ~ /^[[:lower:]]/) {$i = "n"$i} else {$i = "N"$i}}}i' file
对于您的测试用例,它输出:
nword1 NWord2 nword3
无论你在每一行上有多少单词,它都能正常工作。
答案 3 :(得分:0)
AWK
解决方案:
awk '{for(i=1;i<=NF;i++){printf "%s%s"FS,($i~/\<[[:lower:]]/)?"n":"N",tolower($i);}}' text.txt
输出:
nword1 Nword2 nword3
解释:
for(i=1;i<=NF;i++)
- 遍历所有字段/列(即单词)
$i~/\<[[:lower:]]/
- 检查字段/单词是否以小写字母开头
\<
是gawk
正则表达式运算符,它匹配单词开头的空字符串。例如,/\<away/
匹配“away
”但不匹配“stowaway
”。
tolower($i)
- 将单词转换为小写
答案 4 :(得分:0)
在awk中:
$ awk -v f="n" '
{
for(i=1;i<=NF;i++)
sub(/^./, ((c=substr($i,1,1))~/[[:upper:]]/?toupper(f):f) tolower(c),$i)
} 1' file
当然,您也可以从echo
进行管道传输。说明:
awk -v f="n"
char to prepend被带入变量for(i=1;i<=NF;i++)
遍历记录中的每个单词sub(/^./, (
用(c=substr($i,1,1))~/[[:upper:]]/?toupper(f):f) tolower(c),
word的第一个字符存储到c
var,如果是大写,则从f
生成大写字母并从c
$i)
编辑赞成但未经测试。
答案 5 :(得分:0)
根据您向我们展示的样本输入,您只需要:
$ awk '{for (i=1;i<=NF;i++) $i=($i ~ /^[[:upper:]]/ ? "N" : "n") tolower($i)} 1' file
nword1 Nword2 nword3
如果这不是您所需要的,那么请编辑您的问题以显示更好地代表您的真实数据的示例输入。
答案 6 :(得分:-1)
我将概述你可以做的非正式恕我直言:
将文本文件#1读入变量,比如textfile1
在for循环中:
这一切都可以在Bash / Sh中完成。