BASH:根据最长的字符串填充一系列HEX值

时间:2017-05-31 14:12:33

标签: bash awk

我有这种奇怪的情况,我得到了一系列表示二进制数据的HEX值。有趣的是,它们偶尔会有不同的长度,例如:

40000001AA
0000000100
A0000001
000001
20000001B0
40040001B0

我想在末尾附加0,以便根据最长的条目使它们具有相同的长度。因此,在上面的示例中,我有四个长度为10个字符的entires,以'\ n'结尾,还有一些短的(在实际数据中,我有200k个条目,短约1k个)。我想要做的是弄清楚文件中最长的字符串,然后填写并填充短文件;但是,我无法弄明白。任何建议将不胜感激。

4 个答案:

答案 0 :(得分:3)

使用标准的双通awk:

awk 'NR==FNR{if (len < length()) len=length(); next}
     {s = sprintf("%-*s", len, $0); gsub(/ /, "0", s); print s}' file file

40000001AA
0000000100
A000000100
0000010000
20000001B0
40040001B0

或使用gnu wcawk

awk -v len="$(wc -L < file)" '
   {s = sprintf("%-*s", len, $0); gsub(/ /, "0", s); print s}' file

40000001AA
0000000100
A000000100
0000010000
20000001B0
40040001B0

答案 1 :(得分:2)

当您使用using System; using System.Linq; using System.Reflection; using System.Windows; using System.Windows.Controls; using BF = System.Reflection.BindingFlags; namespace WpfApp1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); btn1.Click += (s, e) => Console.WriteLine($"{((Button)s).Content}a pressed"); btn1.Click += Btn1_Click; btn1.MouseEnter += (s, e) => Console.WriteLine($"{((Button)s).Content} mouse entered"); AddButton(); } private void Btn1_Click(object sender, RoutedEventArgs e) { Console.WriteLine($"{((Button)sender).Content}b pressed"); } private void AddButton() { Button btn2 = new Button() { Content = "Button 02" }; panel.Children.Add(btn2); // Copy all event handler from btn1 to btn2 ?? FieldInfo[] fields = btn1.GetType().GetFields(BF.Static | BF.NonPublic | BF.Instance | BF.Public | BF.FlattenHierarchy); foreach (FieldInfo field in fields.Where(x => x.FieldType == typeof(RoutedEvent))) { RoutedEventHandlerInfo[] routedEventHandlerInfos = GetRoutedEventHandlers(btn1, (RoutedEvent)field.GetValue(btn1)); if (routedEventHandlerInfos != null) { foreach (RoutedEventHandlerInfo routedEventHandlerInfo in routedEventHandlerInfos) btn2.AddHandler((RoutedEvent)field.GetValue(btn1), routedEventHandlerInfo.Handler); } } } /// <summary> /// Get a list of RoutedEventHandlers /// Credit: Douglas : https://stackoverflow.com/a/12618521/3971575 /// </summary> /// <param name="element"></param> /// <param name="routedEvent"></param> /// <returns></returns> public RoutedEventHandlerInfo[] GetRoutedEventHandlers(UIElement element, RoutedEvent routedEvent) { // Get the EventHandlersStore instance which holds event handlers for the specified element. // The EventHandlersStore class is declared as internal. PropertyInfo eventHandlersStoreProperty = typeof(UIElement).GetProperty("EventHandlersStore", BF.Instance | BF.NonPublic); object eventHandlersStore = eventHandlersStoreProperty.GetValue(element, null); // If no event handlers are subscribed, eventHandlersStore will be null. // Credit: https://stackoverflow.com/a/16392387/1149773 if (eventHandlersStore == null) return null; // Invoke the GetRoutedEventHandlers method on the EventHandlersStore instance // for getting an array of the subscribed event handlers. MethodInfo getRoutedEventHandlers = eventHandlersStore.GetType().GetMethod("GetRoutedEventHandlers", BF.Instance | BF.Public | BF.NonPublic); return (RoutedEventHandlerInfo[])getRoutedEventHandlers.Invoke(eventHandlersStore, new object[] { routedEvent }); } } } 时,您很有可能还使用其他Bash 工具。在这种情况下,GNU可以很容易地告诉你长度 文件中使用wc选项的最大行。例如:

-L

填充可以这样做:

$ wc -L /tmp/HEX
10 /tmp/HEX

单行:

$ while read i; do echo $(echo "$i"0000000000 | head -c 10); done < /tmp/HEX
40000001AA
0000000100
A000000100
0000010000
20000001B0
40040001B0

答案 2 :(得分:1)

假设您在文件中包含以下值:

file=/tmp/hex.txt

找出最长数字的长度:

longest=$(wc -L < $file)

现在,文件中的每个数字都用零对齐

while read number; do
    printf "%-${longest}s\n" $number | sed 's/ /0/g'
done < $file

这会将脚本打印到stdout:

40000001AA
0000000100
A000000100
0000010000
20000001B0
40040001B0

答案 3 :(得分:1)

一般来说,从一侧或两侧填充一个字符串是(例如,使用5作为所需的字段宽度):

$ echo '17' | awk '{printf "%0*s\n", 5, $0}'
00017

$ echo '17' | awk '{printf "%s%0*s\n", $0, 5-length(), ""}'
17000

$ echo '17' | awk '{w=int((5+length())/2); printf "%0*s%0*s\n", w, $0, 5-w, ""}'
01700

$ echo '17' | awk '{w=int((5+length()+1)/2); printf "%0*s%0*s\n", w, $0, 5-w, ""}'
00170

所以你的例子:

$ awk '{cur=length()} NR==FNR{max=(cur>max?cur:max);next} {printf "%s%0*s\n", $0, max-cur, ""}' file file
40000001AA
0000000100
A000000100
0000010000
20000001B0
40040001B0