删除带有非乌克兰字符的字符串bash
使用文件结构删除带有非乌克兰字符的字符串bash,bash,macos,shell,sed,Bash,Macos,Shell,Sed,使用文件结构 foo_11: "Марія" foo_112: "Superman" FOOTLONG: "Subway" foo_13: "Юлія" 我想从乌克兰字母表中删除所有至少没有一个字符的字符串 脚本: for i in *.txt; do sed '/[^А-ЯЄЇІа-яєїі]+/d' $i >$i.out mv $i.out $i done 什么都不做。怎么了 使用mac bash。此代码将实现您想要的功能(如果我正确理解了您的问题): 结果存储在/tmp/r
foo_11: "Марія"
foo_112: "Superman"
FOOTLONG: "Subway"
foo_13: "Юлія"
我想从乌克兰字母表中删除所有至少没有一个字符的字符串
脚本:
for i in *.txt;
do
sed '/[^А-ЯЄЇІа-яєїі]+/d' $i >$i.out
mv $i.out $i
done
什么都不做。怎么了
使用mac bash。此代码将实现您想要的功能(如果我正确理解了您的问题): 结果存储在
/tmp/result
注意:我不知道乌克兰语,所以我确定我没有包括所有乌克兰语字符,请添加/删除您希望与上述结构匹配的乌克兰语字符。
注2:由于grep-i
的原因,此代码不区分大小写,因此只需添加一次字符(小写或大写)
要将其放在循环中,可以是:
for i in *.txt;
do
grep -i "Я\|Є\|Ї\|І" "$i" > "$i".out
mv "$i".out "$i"
done
编辑:我编辑此答案是为了使其更简单,并为其添加一个循环。假设您定义乌克兰字母的字符类是正确的,以下操作应该有效:
sed '/[А-ЯЄЇІа-яєїі]/!d' file
匹配行中任何位置的乌克兰字母。[А-ЯЯа-єїі]
- 请注意,即使看起来像ASCII字母
的字母实际上也是带有Unicode码点的乌克兰(西里尔)字母aii
U+410 U+406 U+430 U+456
- 请注意,即使看起来像ASCII字母
代码>否定匹配,这意味着只有不包含至少1个乌克兰字母的行匹配
删除这些行d
for f in *.txt; do
sed -i '' '/[А-ЯЄЇІа-яєїі]/!d' "$f" # -i '' is BSD Sed syntax; GNU sed takes just -i
done
至于你试过什么:
- 正如@StefanHegny在对该问题的评论中指出的那样,
在+
未与sed
一起运行以启用扩展正则表达式时不受支持;如果没有-E
,则必须使用繁琐的-E
。(\{1,\}
仅受GNU\+
支持,而不受macOS附带的BSD版本的sed
支持)sed
- 但是,即使是命令的固定版本,
,也不能满足您的需要:它删除至少包含一个非乌克兰字母字符的所有行,这将消除所有输入行,因为它们都具有基于ASCII的字段名,并且包含sed'/[^А-ЯЯ-Я-єїі]{1,\}/d'
:
- 您应该双引号引用变量引用,例如
,以保护它们不受shell扩展的影响:$i
“$i”
- BSD Sed确实支持使用
进行就地更新,但与GNU Sed不同,它要求将空选项参数(表示不应备份输入文件)指定为单独的参数:-i
-i'
- 您的write-to-a-temp-file-first-then-replace-the-original方法同样有效,但通常最好使用以下习惯用法:
。将sed。。。file>file.tmp&&mv file.tmp文件
命令与mv
分开可确保仅当和&
命令成功时才替换原始文件。sed
这就是说,这对处理逻辑错误并没有帮助,就像在本例中一样:尽管没有输出任何内容,
报告了本例中的成功sed
- 您的write-to-a-temp-file-first-then-replace-the-original方法同样有效,但通常最好使用以下习惯用法:
+
修饰符?我的没有,所以我必须写\{1,\}
而不是,即使是OP字符类中看起来像ASCII字母aiai
的字母,实际上也是带有Unicode码点的乌克兰(西里尔文)字母U+410 U+406 U+430 U+456
。我不确定,乌克兰语不是我的强项:-pI将留给OP添加所有乌克兰语字符。@Jamil说你写对了字母)你只是忘了包含范围A-Я。我在堆栈上的某个地方读到,上面的范围仅包括俄语字母,因此我使用此解决方法添加了一些缺少的字母。一个人可能也应该包括Ґ,但这适合我的情况。你的答案可能比我的好,因为它避免了mv
部分,所以我选了你。谢谢,它成功了。然而,我不必使用sed-I'
,即使我没有创建别名,在这种情况下,常规的sed
也可以正常工作。不过,我不得不在其他情况下使用上述解决方法……此外,在每个文件的开头,我都有字符串l_ukrainian:不确定为什么脚本没有删除它,尽管它很适合我。@mklement0您可能误读了“l_ukrainian”在我的情况下没有删除。阿尔克罗:啊,我明白了。这确实令人惊讶。将您的文件传送到cat-v
,查看是否有乌克兰字符。毕竟在那第一行(比如aU+456
i
)。(但听起来你真的想保持这条线,对吗?)
for f in *.txt; do
sed -i '' '/[А-ЯЄЇІа-яєїі]/!d' "$f" # -i '' is BSD Sed syntax; GNU sed takes just -i
done