如何在使用 wc -m 计算多个文件的字符时忽略 '\r'
How to ignore '\r' while counting characters of several files with wc -m
我尝试计算作者“JohnJohnson”使用此命令提交给 git 的字符数:
wc -m $(git log --use-mailmap --no-merges --author="JohnJohnson" --name-only --pretty=format:"" | sort -u)
问题是在 Linux 和 Windows(git-bash) 上它产生不同的结果,至少因为在 Windows 上新的行由两个字符“\r\n”组成。有没有办法让 wc -m 忽略 '\r' 以便我使用相同的命令在两个操作系统上获得一致的结果?
注意: 虽然 运行 wc -m
之前每个文件上的 运行 dos2unix
应该足够了,但我假设) dos2unix
不可用 and/or b) OP 可能会发现还有其他字符(除了 \r
)需要删除。
假设 objective 是生成 与 wc -m
完全相同的输出 ,一个使用用户定义函数的想法:
my_wc () {
local charcount=0 totcount=0
for fname in $@
do
charcount=$(tr -d '\r' < $fname | wc -m)
echo "$charcount $fname"
((totcount+=charcount))
done
echo "$totcount total"
}
应用于OP的例子:
my_wc $(git log --use-mailmap --no-merges --author="JohnJohnson" --name-only --pretty=format:"" | sort -u)
如果 OP 找到要跳过的其他字符(\r
除外),则将它们添加到 tr -d '\r'
调用中。
另一个函数想法,但这个使用 awk
:
my_wc() {
awk 'BEGIN { RS="^$" } # whole file becomes one single, long record
{ gsub("\r","")
n=length([=12=])
tot+=n
print n,FILENAME
}
END { print tot,"total"}' $@
}
在几个示例文件上演示这些函数:
$ head f?
==> f1 <==
a 13
a 5
b 7
a 20
a 3
==> f2 <==
a 13
a 5
b 7
a 20
a 3
==> f3 <==
a 13
a 5
b 7
a 20
a 3
$ dos2unix f?
$ wc -m f?
22 f1
22 f2
22 f3
66 total
$ unix2dos f?
$ wc -m f?
27 f1
27 f2
27 f3
81 total
$ my_wc f?
22 f1
22 f2
22 f3
66 total
在配置为在您的工作树中不进行换行转换的存储库中运行,即关闭 eol
处理。您可以在任何地方执行此操作,例如 git config core.eol false
。避免干扰的最简单方法可能是在临时克隆中执行此操作,
git clone -ns . `mktemp -d`; cd $_
git config core.eol false
git checkout
现在您得到了原始结帐,没有应用 eol munging。
我尝试计算作者“JohnJohnson”使用此命令提交给 git 的字符数:
wc -m $(git log --use-mailmap --no-merges --author="JohnJohnson" --name-only --pretty=format:"" | sort -u)
问题是在 Linux 和 Windows(git-bash) 上它产生不同的结果,至少因为在 Windows 上新的行由两个字符“\r\n”组成。有没有办法让 wc -m 忽略 '\r' 以便我使用相同的命令在两个操作系统上获得一致的结果?
注意: 虽然 运行 wc -m
之前每个文件上的 运行 dos2unix
应该足够了,但我假设) dos2unix
不可用 and/or b) OP 可能会发现还有其他字符(除了 \r
)需要删除。
假设 objective 是生成 与 wc -m
完全相同的输出 ,一个使用用户定义函数的想法:
my_wc () {
local charcount=0 totcount=0
for fname in $@
do
charcount=$(tr -d '\r' < $fname | wc -m)
echo "$charcount $fname"
((totcount+=charcount))
done
echo "$totcount total"
}
应用于OP的例子:
my_wc $(git log --use-mailmap --no-merges --author="JohnJohnson" --name-only --pretty=format:"" | sort -u)
如果 OP 找到要跳过的其他字符(\r
除外),则将它们添加到 tr -d '\r'
调用中。
另一个函数想法,但这个使用 awk
:
my_wc() {
awk 'BEGIN { RS="^$" } # whole file becomes one single, long record
{ gsub("\r","")
n=length([=12=])
tot+=n
print n,FILENAME
}
END { print tot,"total"}' $@
}
在几个示例文件上演示这些函数:
$ head f?
==> f1 <==
a 13
a 5
b 7
a 20
a 3
==> f2 <==
a 13
a 5
b 7
a 20
a 3
==> f3 <==
a 13
a 5
b 7
a 20
a 3
$ dos2unix f?
$ wc -m f?
22 f1
22 f2
22 f3
66 total
$ unix2dos f?
$ wc -m f?
27 f1
27 f2
27 f3
81 total
$ my_wc f?
22 f1
22 f2
22 f3
66 total
在配置为在您的工作树中不进行换行转换的存储库中运行,即关闭 eol
处理。您可以在任何地方执行此操作,例如 git config core.eol false
。避免干扰的最简单方法可能是在临时克隆中执行此操作,
git clone -ns . `mktemp -d`; cd $_
git config core.eol false
git checkout
现在您得到了原始结帐,没有应用 eol munging。