如何在 Bash 中测试一个字符串是否比另一个字符串“更大”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11989373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:32:44  来源:igfitidea点击:

How does testing if a string is 'greater' than another work in Bash?

bashnumeric-conversion

提问by helpermethod

In Bash I can write the following test

在 Bash 中,我可以编写以下测试

[[ "f" > "a" ]]

which results in returning 0, i.e. true. How does bash actually perform this string comparison? From my understanding >does an integer comparison. Does it try to compare the ASCII value of the operands?

这导致返回 0,即 true。bash 如何实际执行此字符串比较?根据我的理解>进行整数比较。它是否尝试比较操作数的 ASCII 值?

采纳答案by Micha? Górny

From help test:

来自help test

  STRING1 > STRING2
                 True if STRING1 sorts after STRING2 lexicographically.

Internally, bash either uses strcoll()or strcmp()for that:

在内部,bash 使用strcoll()strcmp()用于:

else if ((op[0] == '>' || op[0] == '<') && op[1] == '
[[ 2 > 10 ]]     # because "2" comes after "1" in ASCII sort order
[[ 10 -gt 2 ]]   # because 10 is a larger number than 2
(( 10 > 2 ))     # ditto
') { if (shell_compatibility_level > 40 && flags & TEST_LOCALE) return ((op[0] == '>') ? (strcoll (arg1, arg2) > 0) : (strcoll (arg1, arg2) < 0)); else return ((op[0] == '>') ? (strcmp (arg1, arg2) > 0) : (strcmp (arg1, arg2) < 0)); }

The latter actually compares ASCII codes, the former (used when locale is enabled) performs a more specific comparison which is suitable for sorting in given locale.

后者实际上是比较 ASCII 代码,前者(在启用语言环境时使用)执行更具体的比较,适合在给定的语言环境中进行排序。

回答by Gordon Davisson

It's an alphabetical comparison (AIUI the sort order may be influenced by the current locale). It compares the first character of each string, and if the one on the left has a higher value it's true, if lower it's false; if they're the same, then it compares the second character, etc.

这是按字母顺序进行比较(AI​​UI 排序顺序可能受当前语言环境的影响)。它比较每个字符串的第一个字符,如果左边的值较高则为真,如果较低则为假;如果它们相同,则比较第二个字符等。

This is notthe same as integer comparison, for that you use [[ 2 -gt 1 ]]or (( 2 > 1 )). To illustrate the difference between string and integer comparison, consider that all of the following are "true":

这是一样的整数比较,为您使用[[ 2 -gt 1 ]](( 2 > 1 ))。为了说明字符串和整数比较之间的区别,请考虑以下所有内容都是“真”:

[[ 05 < 5 ]]    # Because "0" comes before "5"
[[ +5 < 0 ]]    # Because "+" comes before the digits
[[ -0 < 0 ]]    # Because "-" comes before the digits
[[ -1 < -2 ]]   # Because "-" doesn't change how the second character is compared

Here are some more test that're true as string comparisons, but would be false with integer comparison:

这里有一些更多的测试,作为字符串比较是正确的,但对于整数比较会是错误的:

/* Copyright (C) 1991, 1996, 1997, 2003 Free Software Foundation, Inc. 
   This file is part of the GNU C Library. 

   The GNU C Library is free software; you can redistribute it and/or 
   modify it under the terms of the GNU Lesser General Public 
   License as published by the Free Software Foundation; either 
   version 2.1 of the License, or (at your option) any later version. 

   The GNU C Library is distributed in the hope that it will be useful, 
   but WITHOUT ANY WARRANTY; without even the implied warranty of 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
   Lesser General Public License for more details. 

   You should have received a copy of the GNU Lesser General Public 
   License along with the GNU C Library; if not, write to the Free 
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
   02111-1307 USA.  */ 

#include <string.h> 
#include <memcopy.h> 

#undef strcmp 

/* Compare S1 and S2, returning less than, equal to or 
   greater than zero if S1 is lexicographically less than, 
   equal to or greater than S2.  */ 
int 
strcmp (p1, p2) 
     const char *p1; 
     const char *p2; 
{ 
  register const unsigned char *s1 = (const unsigned char *) p1; 
  register const unsigned char *s2 = (const unsigned char *) p2; 
  unsigned reg_char c1, c2; 

  do 
    { 
      c1 = (unsigned char) *s1++; 
      c2 = (unsigned char) *s2++; 
      if (c1 == '##代码##') 
        return c1 - c2; 
    } 
  while (c1 == c2); 

  return c1 - c2; 
} 

回答by olivecoder

Yes, it compares the ascii value and if equal then repeat the comparison in the next character.

是的,它比较 ascii 值,如果相等,则在下一个字符中重复比较。

##代码##