【问题标题】:Linux sort command not working with hyphens and colons in stringLinux排序命令不适用于字符串中的连字符和冒号
【发布时间】:2021-09-06 13:34:30
【问题描述】:

不乏与此问题相关的问题和答案,但我找不到任何具体谈论导致问题的多个特殊字符...仅涉及一个特定字符。

我的数据集示例同时包含连字符和冒号,其中连字符出现在字符串的第一部分,冒号是我要排序的“列”之间的分隔符...例如:

s3:GetObject
ssm:GetParameter
ssm:GetParameters
ssm:GetParametersByPath
secretsmanager:GetSecretValue
cognito-identity:GetOpenIdToken
cognito-identity:GetOpenIdTokenForDeveloperIdentity
cognito-identity:GetCredentialsForIdentity
connect:GetFederationToken
ecr:GetAuthorizationToken
gamelift:RequestUploadCredentials
sts:GetFederationToken
sts:GetSessionToken
s3:GetObject
secretsmanager:GetSecretValue
ssm:GetParameter
ssm:GetParameters
ssm:GetParametersByPath

我想通过sort | uniq 或等效的方式获取以下信息:

cognito-identity:GetCredentialsForIdentity
cognito-identity:GetOpenIdToken
cognito-identity:GetOpenIdTokenForDeveloperIdentity
connect:GetFederationToken
ecr:GetAuthorizationToken
gamelift:RequestUploadCredentials
s3:GetObject
secretsmanager:GetSecretValue
ssm:GetParameter
ssm:GetParameters
ssm:GetParametersByPath
sts:GetFederationToken
sts:GetSessionToken

但我无法达到这些结果。事实上,使用标准sort | uniq 以及所有sort -k 2,2 -t:LC_COLLATE=C sort 以及类似的变体,我得到了很多未排序的数据返回。例如:

| sort -uLC_COLLATE=C sort,甚至sort -k 1 -k 2 -t- | uniq都会导致:

cognito-identity:GetOpenIdToken
s3:GetObject
cognito-identity:GetCredentialsForIdentity
...

我最接近的是使用| sort -k 2 -t- | uniq 来获取:

s3:GetObject
connect:GetFederationToken
ecr:GetAuthorizationToken
gamelift:RequestUploadCredentials
secretsmanager:GetSecretValue
ssm:GetParameter
ssm:GetParameters
ssm:GetParametersByPath
sts:GetFederationToken
sts:GetSessionToken
cognito-identity:GetCredentialsForIdentity
cognito-identity:GetOpenIdToken
cognito-identity:GetOpenIdTokenForDeveloperIdentity

...但这仍然远未达到我想要或期望的水平。

有谁知道如何进行这项工作?我一直在寻找简单的 awk 替代方案,并且对任何可行的解决方案都很满意。

编辑:

回复评论...

我正在操作一个文件,我正在使用的完整命令,以及您建议的添加的 LC_ALL=C cat -vet(感谢您的提示!),看起来像:

cloudsplaining scan-policy-file --input-file $FILENAME.json | grep Actions | sed 's/Actions.*: //g' | tr ' ' '\n' | tr -d ',' | LC_ALL=C cat -vet

^[[1msecretsmanager:GetSecretValue$
ssm:GetParameter$
ssm:GetParametersByPath$
s3:GetObject$
ssm:GetParameters$
^[[1mconnect:GetFederationToken$
gamelift:GetInstanceAccess$
cognito-identity:GetOpenIdTokenForDeveloperIdentity$
ec2:GetPasswordData$
sts:GetSessionToken$
cognito-idp:GetSigningCertificate$
cognito-identity:GetCredentialsForIdentity$
ecr:GetAuthorizationToken$
cognito-identity:GetOpenIdToken$
sts:GetFederationToken$
^[[1ms3:GetObject$
secretsmanager:GetSecretValue$
ssm:GetParameter$
ssm:GetParameters$
ssm:GetParametersByPath$

所以,是的,有一些垃圾。不知道它来自哪里或为什么,但我会说这绝对是导致问题和我困惑的原因。感谢您指出...关于如何解决它的任何想法?

编辑 2(已解决):

在对原始输出使用| LC_ALL=C cat -vet 技巧后解决了这个问题,该技巧向我展示了[[1m 的来源,并最终在我的sed 中添加了前面的.* 修复了它!与第一次编辑相比,可以看出:

cloudsplaining scan-policy-file --input-file $FILENAME.json | grep Actions | sed 's/.*Actions.*: //g' | tr ' ' '\n' | tr -d ',' | LC_ALL=C cat -vet

secretsmanager:GetSecretValue$
ssm:GetParameters$
ssm:GetParametersByPath$
s3:GetObject$
ssm:GetParameter$
ec2:GetPasswordData$
cognito-identity:GetOpenIdTokenForDeveloperIdentity$
cognito-idp:GetSigningCertificate$
sts:GetFederationToken$
ecr:GetAuthorizationToken$
cognito-identity:GetCredentialsForIdentity$
gamelift:GetInstanceAccess$
cognito-identity:GetOpenIdToken$
connect:GetFederationToken$
sts:GetSessionToken$
s3:GetObject$
secretsmanager:GetSecretValue$
ssm:GetParameter$
ssm:GetParameters$
ssm:GetParametersByPath$

现在| sort | uniq 也可以正常工作了。经验教训。

【问题讨论】:

  • sort -usort | uniq 都为我产生了预期的结果。您的文件是否有某种不可见的字符或某些东西弄乱了它?尝试使用LC_ALL=C cat -vet filename 查看它,看看是否有任何显示。它应该在每行的末尾添加一个$;除此之外的任何东西都算作“奇怪”。
  • @GordonDavisson 感谢您指出这一点。我不知道。我确实看到有一些看不见的字符。更新了我的问题以显示结果。
  • @TryTryAgain 也许你可以去掉^[[1m之类的特殊字符或者重写cat file > new_file之类的原始文件,然后按照你的规则排序,通过“unix.stackexchange.com/questions/339513/…”检查。
  • cloudsplaining 是否可以选择为其输出着色?
  • @GordonDavisson 它没有,但我知道这就是它的来源,当我删除字符串时,我没有删除 [[1m .. 前置 .* 为我解决了它。

标签: bash sorting awk uniq


【解决方案1】:

您必须认真考虑要排序的内容。本质上,您似乎想按第一个字段进行唯一排序。为此,您将使用:

sort -t: -u -k1 file

-t: 设置字段分隔符,-u 唯一,-k1 通过第一个键。 (您可以省略-k1,因为这将是默认值)所以只需使用sort -t: -u file 进行排序就可以了。

使用/输出示例

您在file 中输入,您将收到:

$ sort -t: -u -k1 file
cognito-identity:GetCredentialsForIdentity
cognito-identity:GetOpenIdToken
cognito-identity:GetOpenIdTokenForDeveloperIdentity
connect:GetFederationToken
ecr:GetAuthorizationToken
gamelift:RequestUploadCredentials
s3:GetObject
secretsmanager:GetSecretValue
ssm:GetParameter
ssm:GetParameters
ssm:GetParametersByPath
sts:GetFederationToken
sts:GetSessionToken

如果我正确地阅读了您的问题,您所追求的是什么。

【讨论】:

    【解决方案2】:

    这似乎应该并且会一直按预期工作。

    @GordonDavisson 以评论的形式提供了最有用的信息:

    您的文件是否有某种不可见的字符或其他东西 搞砸了?尝试使用LC_ALL=C cat -vet filename 和查看它 看看这是否表明了什么。它应该在每个末尾添加一个$ 线;除此之外的任何东西都算作“奇怪”。

    一旦我看到实际发生的情况,就很容易修复。 OP 的编辑中包含的详细信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-06
      • 2021-11-07
      • 2016-12-20
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      • 2014-07-13
      相关资源
      最近更新 更多